package com.tjtt.tdm.system.action;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpSession;

import org.acegisecurity.context.SecurityContextImpl;
import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

import com.tjtt.common.utils.StringUtil;
import com.tjtt.tdm.base.BaseAction;
import com.tjtt.tdm.base.Constants;
import com.tjtt.tdm.exception.ServiceException;
import com.tjtt.tdm.system.bean.ConfigInfo;
import com.tjtt.tdm.system.bean.LogInfo;
import com.tjtt.tdm.system.bean.OnlineCounter;
import com.tjtt.tdm.system.bean.Role;
import com.tjtt.tdm.system.bean.Users;
import com.tjtt.tdm.system.service.ConfigService;
import com.tjtt.tdm.system.service.LogService;
import com.tjtt.tdm.system.service.UserService;
/**
 * 用户登陆
 * @author liangjy
 *
 */
public class LoginAction extends BaseAction {
	private static final long serialVersionUID = 5156288255337069381L;

	private static final Log log = LogFactory.getLog(LoginAction.class);
	private LogService logService;
	private UserService userService;
    private ConfigService configService;
    private ConfigInfo configInfo;
    /**记录登陆失败次数*/
    private long failcount;
    /**系统设定中的密码错误锁定次数*/
	private long lockcount;
	private String password;
	private String loginName;
	private String loginType; // 登录类型
	private String randomSignature; // 根据随机数生成的证书签名
	private String random;
	
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	/**
	 * 用户名登录
	 * @return String
	 */
	public String loginByName() throws Exception {
		try {
			Users users = userService.findUsersByName(loginName);
			configInfo =  configService.findConfig();//获取系统配置项
			String ip = getRequest().getRemoteAddr();
//			if(Constants.ipMap.get(ip)!=null && Constants.ipMap.get(ip)){//如果被锁定
//				getRequest().setAttribute("message", "IP已被锁定，请"+configInfo.getSysLocktime()+"分钟后再试!");
//				return "LoginFail";
//			}
			final String act=loginName;//转换为final在timertask中调用
			final String actip = ip;
			String failcount = "0";
			if(users.getPwdFailCount()!=null){
				failcount = String.valueOf(users.getPwdFailCount());
			}
			int failnum = 0;
			if(!StringUtil.isEmpty(failcount)){
				failnum = Integer.parseInt(failcount);
			}
			if("1".equals(users.getLockFlag())){//如果被锁定
				getRequest().setAttribute("message", "账号已被锁定，请"+configInfo.getSysLocktime()+"分钟后再试!");
				return "LoginFail";
			}
			Users user = userService.checkUser(loginName, password);
			if (user == null) {
				failnum++;
				if(failnum >= configInfo.getSysLockCount()){//改成锁定
					Constants.ipMap.put(ip, true);
//					user.setDeptid(ip);
					users.setLockFlag("1");
					users.setPwdFailCount(Long.parseLong(String.valueOf(failnum)));
					userService.editUserInfo(users);//修改登录失败次数
					addMessage("账号已锁定，请"+configInfo.getSysLocktime()+"分钟后再试!");
					//接下来就是计时器发挥作用的时候
					TimerTask tt=new TimerTask() {
						public void run() {
							try {
								Users user = userService.findUsersByName(act);
								user.setLockFlag("0");
								user.setPwdFailCount(0l);
								userService.editUserInfo(user);//修改登录失败次数
								Constants.ipMap.remove(actip);
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					};
					Timer t=new Timer();
					t.schedule(tt,60000*configInfo.getSysLocktime());  //这里的18W是指3分钟  单位是毫秒 
				}else{
//					user.setDeptid(ip);
					users.setPwdFailCount(Long.parseLong(String.valueOf(failnum)));
					userService.editUserInfo(users);//修改登录失败次数
					addMessage("用户名或密码不正确,你还有"+String.valueOf(configInfo.getSysLockCount()-failnum)+"次机会!");
				}
				return "LoginFail";
			}
			if (null != user) {
			    if(user.getLockFlag().equals("0")){
					Set<Role> roles = user.getRoles();
					String role = "";
					for(Role r:roles){ 
						role += r.getRoleId() + ",";
					} 
					if(!"".equals(role)){
						role = role.substring(0,role.length()-1);
					}
					//获取常用的功能菜单
					//List oftenMenuList = userService.findOftenMenu(String.valueOf(user.getUserid()));
					//获取所有的菜单
					List firstmenuList = userService.findFirstMenu(role);
					HttpSession session = this.getHttpSession();	
					//session.setAttribute("OFTEN_MENU_INFO", oftenMenuList);
					session.setAttribute("MENU_INFO", firstmenuList);
					session.setAttribute("ROLE_INFO", role);
					session.setAttribute("TDM_USER", user);
					session.setAttribute("USER_DEPT", user.getOrganization().getOrgId());
					session.setAttribute("ORG_ID", user.getOrganization().getOrgId());
					session.setAttribute("ORG_NAME",user.getOrganization().getOrgName());
					session.setAttribute("USER_DEPT_NAME", user.getOrganization().getOrgName());
					session.setAttribute("TDM_USER_ID", user.getUserid());
					session.setAttribute("username", user.getUsername());
					session.setAttribute("loginname", user.getLoginname());
					session.setAttribute("loginTime", new Date());
					session.setAttribute("SYS_PAGECOUNT", configInfo.getSysPageCount());
					session.setAttribute("SYS_FILEPATH", configInfo.getSysFilepath());
					session.setAttribute("SYS_MENU_COUNT", configInfo.getSysMenuCount());
					session.setAttribute("SYS_EQUIPMENT_DAY", configInfo.getSysEquipmentDay());
					session.setAttribute("servername", this.getRequest().getContextPath());
					session.setAttribute("HEADER", user.getImgAddress());
					// 添加在线用户
					OnlineCounter.addUser(session.getId(), user.getUserid(),
							user.getUsername(), user.getLoginname(), user.getOrganization().getOrgName());
//									session.setAttribute("userMaxNum", maxNum);//最大用户数
					user.setLoginTime(new Date());
					userService.editUserInfo(user);
					//登陆成功，清空用户表中的登陆失败次数记录 
					log.info(loginName + " login in success. ");
					logService.saveLogInfo(this.getLogBase(), "登录系统", "登录系统", "系统登录成功",3);
					Cookie[] cookies = getRequest().getCookies();
					String frametype = "";  
					if(cookies!=null)      
					{   
						for (int i = 0; i < cookies.length; i++)      
						{
							Cookie c = cookies[i];           
							if(c.getName().equalsIgnoreCase("jframetype"))      
							{      
								frametype = c.getValue();      
							}      
						}
					}
					return "SUCCESS";
				}else{
					addActionError(getText("login.failure"));
					logService.saveLogInfo(this.getLogBase(),"登录系统", "登录系统", "系统登录失败",3);
					getRequest().setAttribute("message", "用户被锁定！请联系管理员！");
					return "LoginFail";
				}
			}  
				return "LoginFail";
		} catch (Exception e) {
			e.printStackTrace();
			return "LoginFail";
		}
		
		
	}

	public String executeLogin() throws Exception {		
		HttpSession session = this.getHttpSession();		
		try {			
			if(1==1){
					String loginname = (String)session.getAttribute("ACEGI_SECURITY_LAST_USERNAME");
					boolean isCanLogin = false;
					Users users = userService.findUsersByName(loginname);
					configInfo = configService.findConfig();
					//记录失败登陆次数
					failcount = 0;
					lockcount = configInfo.getSysLockCount();
					int locktime = configInfo.getSysLocktime();
					if(users!=null){
						String lockFlag = users.getLockFlag();		
						String delFlag = users.getDelFlag();
						if(delFlag.equals("2"))
						{
							addActionError(getText("login.failure"));
							getRequest().setAttribute("message", "该用户已被删除！");
							//logService.saveLogInfo(this.getLogBase(), "登录系统", "登录系统", "该用户已被删除",3);
							return "LoginFail";
						}
						if(users.getPwdFailCount()!=null)
						{	
							failcount = users.getPwdFailCount();
						}
						if(lockFlag.equals("1")){
							Date logintime = users.getLoginTime();
							long dayNumber = 0;
							//1小时=60分钟=3600秒=3600000
							long mins = 60L * 1000L;
							SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
							String time = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(logintime);
							String sysdate = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
							Date d1 = df.parse(time);
							Date d2 = df.parse(sysdate);
							//dayNumber:系统当前时间sysdate与time的分钟差
							dayNumber = (d2.getTime() - d1.getTime()) / mins;
							 //如果当前时间大于锁定时间，解锁锁定用户
							if(dayNumber>locktime) 
							{
							   failcount = 0;
							   users.setLockFlag("0");
							   users.setPwdFailCount(0L);
							   users.setLockTime(null);
							   userService.updateUserInfo(users);
							   isCanLogin = true;
							}else{
								addActionError(getText("login.failure"));
								getRequest().setAttribute("message", "账号被锁定！请于"+locktime+"分钟后再登陆，或者请联系管理员！");
								logService.saveLogInfo(this.getLogBase(), "登录系统", "登录系统", "账号被锁定",3);
								return "LoginFail";
							}
						}else{
							isCanLogin = true;
						}
					}else{
						addActionError(getText("login.failure"));
						getRequest().setAttribute("message", "用户不存在！");
						logService.saveLogInfo(this.getLogBase(), "登录系统", "登录系统", "用户不存在",3);
						return "LoginFail";
					}if(isCanLogin){	
							SecurityContextImpl sci = (SecurityContextImpl) session.getAttribute("ACEGI_SECURITY_CONTEXT");
							if (null != sci) {
								UsernamePasswordAuthenticationToken ath = (UsernamePasswordAuthenticationToken) sci.getAuthentication();
								if (null != ath) {
									if (ath.isAuthenticated()) {
										String loginName = ((org.acegisecurity.userdetails.User) ath.getPrincipal()).getUsername();
										String password = ((org.acegisecurity.userdetails.User) ath.getPrincipal()).getPassword();
										Users user = userService.checkUser(loginName, password);
									if (null != user) {
										    if(user.getLockFlag().equals("0")){
												Set<Role> roles = user.getRoles();
												String role = "";
												for(Role r:roles){ 
													role += r.getRoleId() + ",";
												} 
												if(!"".equals(role)){
													role = role.substring(0,role.length()-1);
												}
												//获取常用的功能菜单
												List oftenMenuList = userService.findOftenMenu(String.valueOf(user.getUserid()));
												//获取所有的菜单
												List firstmenuList = userService.findFirstMenu(role);
												session.setAttribute("OFTEN_MENU_INFO", oftenMenuList);
												configInfo =  configService.findConfig();
												session.setAttribute("MENU_INFO", firstmenuList);
												session.setAttribute("ROLE_INFO", role);
												session.setAttribute("TDM_USER", user);
												session.setAttribute("USER_DEPT", user.getOrganization().getOrgId());
												session.setAttribute("ORG_ID", user.getOrganization().getOrgId());
												session.setAttribute("ORG_NAME",user.getOrganization().getOrgName());
												session.setAttribute("USER_DEPT_NAME", user.getOrganization().getOrgName());
												session.setAttribute("TDM_USER_ID", user.getUserid());
												session.setAttribute("username", user.getUsername());
												session.setAttribute("loginname", user.getLoginname());
												session.setAttribute("loginTime", new Date());
												session.setAttribute("SYS_PAGECOUNT", configInfo.getSysPageCount());
												session.setAttribute("SYS_FILEPATH", configInfo.getSysFilepath());
												session.setAttribute("SYS_MENU_COUNT", configInfo.getSysMenuCount());
												session.setAttribute("SYS_EQUIPMENT_DAY", configInfo.getSysEquipmentDay());
												session.setAttribute("servername", this.getRequest().getContextPath());
												// 添加在线用户
												OnlineCounter.addUser(session.getId(), user.getUserid(),
														user.getUsername(), user.getLoginname(), user.getOrganization().getOrgName());
			//									session.setAttribute("userMaxNum", maxNum);//最大用户数
												//登陆成功，清空用户表中的登陆失败次数记录
												users.setPwdFailCount(0L);
												log.info(loginName + " login in success. ");
												logService.saveLogInfo(this.getLogBase(), "登录系统", "登录系统", "系统登录成功",3);
											}else{
												addActionError(getText("login.failure"));
												logService.saveLogInfo(this.getLogBase(),"登录系统", "登录系统", "系统登录失败",3);
												getRequest().setAttribute("message", "用户被锁定！请联系管理员！");
												return "LoginFail";
											}
										} else {
											addActionError(getText("login.failure"));
											logService.saveLogInfo(this.getLogBase(),"登录系统", "登录系统", "系统登录失败",3);
											getRequest().setAttribute("message", "用户名或密码错误！请重新输入");
											return "LoginFail";
										}
									}
								} else {
									addActionError(getText("login.failure"));
									getRequest().setAttribute("message", "用户名或密码错误！请重新输入");
									logService.saveLogInfo(this.getLogBase(), "登录系统", "登录系统", "登录系统失败",3);
									return "LoginFail";
								}
							} else {
								addActionError(getText("login.failure"));
								failcount ++;
								if(users!=null){
									users.setPwdFailCount(failcount);
									userService.updateUserInfo(users);
									if(failcount>=lockcount){
										users.setLockFlag("1");
										users.setLoginTime(new Date());
										userService.updateUserInfo(users);
										addActionError(getText("login.failure"));
										getRequest().setAttribute("message", "密码输入次数超过"+lockcount+"次，账号被锁定！");
										logService.saveLogInfo(this.getLogBase(), "登录系统", "登录系统", "账号被锁定",3);
										return "LoginFail";
									}
								}
								getRequest().setAttribute("message", "用户名或密码错误！请重新输入");
								logService.saveLogInfo(this.getLogBase(), "登录系统", "登录系统", "登录系统失败",3);
								return "LoginFail";
							}
				    }	
				}else{
					addActionError("系统未激活状态,请激活系统再登录。");
					log.info("系统未注册。。。。。");
					return "Active";
				}
		} catch (Exception e) {
			String targetUrl = (String) session.getAttribute("ACEGI_SECURITY_TARGET_URL");
			targetUrl = null;
			session.setAttribute("ACEGI_SECURITY_TARGET_URL", targetUrl);
			log.error(e);
			addActionError(getText("login.failure"));
			logService.saveLogInfo(this.getLogBase(), "登录系统", "登录系统","登录系统失败",3);
			return "LoginFail";
		}
		return SUCCESS;
	}
	
	/**
	 * 退出
	 * @return
	 * cm 2011-9-5
	 * @throws ServiceException 
	 */
	public String userLoginOut() throws ServiceException{
		try {
			// 销毁session
			LogInfo logInfo = this.getLogBase();
			LOG.info("销毁Session-----------------------------------------");
			// 删除在线用户
			OnlineCounter.deleteUser(getRequest().getSession().getId());
			getRequest().getSession().removeAttribute("ACEGI_SECURITY_CONTEXT");
			getRequest().getSession().invalidate();
			String path = getRequest().getContextPath();
			String common_basePath = getRequest().getScheme() + "://"
			+ getRequest().getServerName() + ":" + getRequest().getServerPort()
				+ getRequest().getContextPath() + "/";
			ServletActionContext
					.getResponse()
					.getWriter()
					.write(common_basePath+"/login.jsp");
			logService.saveLogInfo(logInfo, "退出系统", "退出系统", "退出系统成功",3);
		} catch (Exception e) {
			e.printStackTrace();
			logService.saveLogInfo(this.getLogBase(), "退出系统", "退出系统", "退出系统失败",3);
			return ERROR;
		}
		return null;
//		HttpSession session = this.getHttpSession();
//			session.removeAttribute("ACEGI_SECURITY_CONTEXT");
//			try {
//				logService.saveLogInfo(this.getLogBase(), "退出系统", "退出系统", "退出系统成功");
//			} catch (Exception e) {
//				logService.saveLogInfo(this.getLogBase(), "退出系统", "退出系统", "退出系统失败");
//				log.info("系统未注册。。。。。");
//			}	
//		return SUCCESS;
	}
	public String logout() {
		try {
			// 销毁session
			LOG.info("销毁Session-----------------------------------------");
			getRequest().getSession().invalidate();
			ServletActionContext
					.getResponse()
					.getWriter()
					.write(
							"<script>window.parent.parent.location.href='login.jsp';</script>");
		} catch (Exception e) {
			e.printStackTrace();
			return ERROR;
		}
		return null;
	}

	public void setLogService(LogService logService) {
		this.logService = logService;
	}

	public void setConfigService(ConfigService configService) {
		this.configService = configService;
	}

	public ConfigInfo getConfigInfo() {
		return configInfo;
	}

	public void setConfigInfo(ConfigInfo configInfo) {
		this.configInfo = configInfo;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getLoginType() {
		return loginType;
	}

	public void setLoginType(String loginType) {
		this.loginType = loginType;
	}

	public String getRandomSignature() {
		return randomSignature;
	}

	public void setRandomSignature(String randomSignature) {
		this.randomSignature = randomSignature;
	}

	public String getRandom() {
		return random;
	}

	public void setRandom(String random) {
		this.random = random;
	}
	
}
